<?php
/**
 * Created by PhpStorm.
 * User: 76683
 * Date: 2018/7/16
 * Time: 23:00
 */

namespace app\sd\admin;


use app\admin\controller\Admin;
use app\api\until\es\ESConf as ES;
use app\sd\model\WeDayTopic;
use app\common\builder\ZBuilder;
use app\sd\model\WeTopic as WeTopicModel;
use app\sd\model\WeCategory;
use think\Db;
use think\exception\DbException;
use think\Request;
use app\api\model\WeTopic as HotTopicModel;
use app\api\until\es\Indices;
use app\api\until\es\Doc;


class WeTopic extends Admin implements ES
{
    protected $weCategoryModel = null;

    function __construct(Request $request = null)
    {
        $this->weCategoryModel = new WeCategory();
        parent::__construct($request);
    }

    public function index()
    {
        $map = $this->getMap();
        $order = $this->getOrder();
        $category_list = $this->weCategoryModel->categoryList();
        $data_list = WeTopicModel::topicList($map, $order);
        $user_list = \app\sd\model\WeUsers::where(['status' => 1, 'is_delete' => 0, 'type' => 2])->column('nick_name', 'id');
        $fields = [
            ['hidden', 'id'],
            ['textarea', 'content', '话题内容'],
            ['images', 'photos', '话题图片'],
            ['select', 'user_id', '选择用户', '', $user_list],
            ['select', 'category_id', '选择领域', '', $category_list],
            ['hidden', 'create_time', time()],
            ['hidden', 'update_time', time()]
        ];
        $columns = [
            ['id', 'ID'],
            ['content', '话题'],
            ['photos', '话题配图', 'pictures'],
            ['nick_name', '用户昵称'],
            ['we_nick_name', '用户小程序昵称'],
            ['user_id', '用户ID'],
            ['category_name', '领域'],
            ['likes', '点赞数'],
            ['details', '评论数'],
            ['create_time', '创建时间', 'datetime'],
            ['update_time', '更新时间', 'datetime'],
            ['right_button', '操作', 'btn']
        ];

        $today_topic_btn = [
            'title' => '设为添加到今日话题',
            'href' => url('dayTopic', ['id' => '__id__']) . '?_pop=1',
            'class' => 'pop btn btn-xs btn-default',
            'icon' => 'fa fa-plus'
        ];
        return ZBuilder::make('table')
            ->addTopSelect('category_id', '领域', $category_list)
            ->autoAdd($fields, 'we_topic')
            ->autoEdit($fields, 'we_topic')
            ->addRightButtons(['today_topic_btn' => $today_topic_btn, 'delete'])
            ->setTableName('we_topic')
            ->addColumns($columns)
            ->setSearch(['t.user_id'=>'用户ID','u.we_nick_name'=>'用户小程序内昵称'])
            ->setRowList($data_list)
            ->fetch();
    }

    public function dayTopic()
    {
        if ($this->request->isGet()) {
            $id = input('id', 0);
            $formItems = [
                ['hidden', 'topic_id', $id],
                ['date', 'show_date', '请选择日期', '', date('Y-m-d', time())]
            ];
            return ZBuilder::make('form')
                ->addFormItems($formItems)
                ->fetch();
        }

        if ($this->request->isPost()) {
            $data = $this->request->post();
            $res = $this->validate($data, 'DayTopic');
            if (true !== $res) {
                $this->error($res);
            }

            $map = [
                'is_delete' => 0,
                'show_date' => strtotime($data['show_date'])
            ];
            $exists = WeDayTopic::where($map)->select();
            if (empty($exists)) {
                $saveData['topic_id'] = $data['topic_id'];
                $saveData['show_date'] = strtotime($data['show_date']);
                $saveData['create_time'] = time();
                $saveData['update_time'] = time();
                $result = WeDayTopic::create($saveData);
                if ($result) {
                    $this->success('添加今日话题成功');
                } else {
                    $this->error('添加今日话题失败');
                }
            } else {
                $this->error($data['show_date'] . '已存在当日话题，请删除后再添加');
            }
        }
    }

    /**
     * @return mixed
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function hot()
    {
        $model = new HotTopicModel();
        $data_list = $model->hotTopic();
        $config = module_config('sd');
        //获取原始数值
        if (empty($data_list)) {
            $data_list = [
                'id' => '',
                'content' => '最近' . $config['hot_time'] . '小时内没有热门话题数据',
                'photos' => '',
                'nick_name' => '',
                'category_id' => '0',
                'likes' => '',
                'create_time' => '',
            ];
        } else {
            $data_list = $data_list->getData();
        }
        $arr[0] = $data_list;
        $columns = [
            ['id', 'ID'],
            ['content', '话题'],
            ['photos', '话题配图', 'pictures'],
            ['nick_name', '用户昵称'],
            ['category_id', '领域', 'callback', function ($value) {
                $categoryInfo = WeCategory::get($value);
                if (empty($categoryInfo)) {
                    return '';
                } else {
                    return $categoryInfo->name;
                }
            }],
            ['likes', '点赞数'],
            ['create_time', '创建时间', 'datetime'],
//            ['update_time', '更新时间', 'datetime'],
            ['right_button', '操作', 'btn']
        ];

        $today_topic_btn = [
            'title' => '设为添加到今日话题',
            'href' => url('dayTopic', ['id' => '__id__']) . '?_pop=1',
            'class' => 'pop btn btn-xs btn-default',
            'icon' => 'fa fa-plus'
        ];
        return ZBuilder::make('table')
            ->addRightButtons(['today_topic_btn' => $today_topic_btn])
            ->addColumns($columns)
            ->setRowList($arr)
            ->fetch();
    }


    public function delete($record = [])
    {
        $id = input('ids');
        $handled = input('is_handled');
        $type = input('type');
        if ($type != 1){
            $this->redirect('detail/delete',['ids'=>$id,'is_handled'=>$handled,'back'=>'we_report.index']);
        }
        if ($handled){
            $res = WeTopicModel::update(['is_delete'=>1,'is_handled'=>1],['id'=>$id]);
            if ($res){
                return $this->success('删除成功',url('we_report/index'));
            }else{
                return $this->error('删除失败',url('we_report/index'));
            }
        }else{
            return parent::delete($record); // TODO: Change the autogenerated stub
        }
    }

    ################################################################################
    ################################################################################
    ################################################################################
    ################################################################################
    ################################################################################
    ###################################
    ###################################
    ###################################     ES操作部分
    ###################################     ES操作部分
    ###################################     ES操作部分
    ###################################
    ###################################
    ################################################################################
    ################################################################################
    ################################################################################
    ################################################################################

    /**
     * @return mixed
     */

    public function syn()
    {
        return $this->fetch('syn');
    }

    /**
     * 查询索引信息
     * @return array
     */
    public function indicesInfo()
    {
        $indices = new Indices();
        $exits = $indices->setParams(ES::TOPIC_INDEX)->isExits();
        if ($exits) {
            return json(['status' => 1, 'msg' => '查询到话题索引,准备删除', 'act' => 'del']);
        } else {
            return json(['status' => 1, 'msg' => '未查询到话题索引,准备创建话题索引', 'act' => 'create']);
        }
    }

    public function delIndices()
    {
        $indices = new Indices();
        $res = $indices->setParams(ES::TOPIC_INDEX)->deleteIndices();
        if ($res['acknowledged'] == 1) {
            return json(['status' => 1, 'msg' => '创建索引成功,正在创建话题索引', 'act' => 'create']);
        } else {
            return json(['status' => 1, 'msg' => '删除索引失败,请重新开始同步', 'act' => 'restart']);
        }
    }

    public function createIndices()
    {
        $indices = new Indices();
        $res = $indices->setParams(ES::TOPIC_INDEX)->createIndices();
        if ($res['acknowledged'] == true) {
            return json(['status' => 1, 'msg' => '创建索引成功,正在开始查询话题量', 'act' => 'syn']);
        } else {
            return ['status' => 1, 'msg' => '创建索引失败,请重新开始同步', 'act' => 'restart'];
        }
    }

    /**
     * @return array
     */
    public function topicCount()
    {
        try {
            $count = count(WeTopicModel::all());
        } catch (DbException $exception) {
            return json(['status' => 0, 'msg' => $exception->getMessage()]);
        }
        $per = 1000;
        $page = ceil($count / $per);
        return json(['status' => 1, 'msg' => '获取话题量成功,总计' . $count . '条话题' . $page . '页' . '每页' . $per . '条', 'data' => ['total' => $count, 'page' => $page, 'per' => 1000]]);
    }

    /**
     * @return array
     * @throws \Exception
     */
    public function synTopic()
    {
        $request_data = $this->request->post();
        $res = $this->validate($request_data, ['page' => 'require|number'], ['page.require' => '页码丢失', 'page.number' => '页码错误']);
        if (true !== $res) {
            return json(['status' => 0, 'msg' => $res]);
        }
        $page = $request_data['page'];
        $per = 1000;
        $model = new WeTopicModel();
        $start = ($page - 1) * $per;
        $end = $page * $per;
        try {
            $topic_list = $model->field('es_id', true)->limit($start, $end)->select();
            if (empty($topic_list)) {
                return json(['status' => 1, 'msg' => '没查询到数据或已经更新完成']);
            }
        } catch (DbException $exception) {
            return json(['status' => 0, 'msg' => $exception->getMessage()]);
        }
        $doc = new Doc();
        Db::startTrans();
        $updateData = [];
        $history_es = [];//用来删除当前失败的_id
        foreach ($topic_list as $item) {
            $esResponse = $doc->setParams(ES::TOPIC_INDEX, ES::TOPIC_TYPE, $item)->createDoc();
            if ((isset($esResponse['result']) && $esResponse['result'] == 'created') || $esResponse['_shards']['successful'] == 1 || $esResponse['_shards']['created'] == true) {
                $history_es[] = $esResponse['_id'];
                $temp = ['id' => $item['id'], 'es_id' => $esResponse['_id']];
                $updateData[] = $temp;
                unset($temp);
            } else {
                //删除刚刚这一批
                $delResponse = $doc->setParams(ES::TOPIC_INDEX, ES::TOPIC_TYPE, $doc->beforeBulk(ES::BULK_DELETE, $history_es))->deleteByBatch();
                if ($delResponse['result'] !== 'deleted') {
                    return json(['status' => 0, 'msg' => '同步失败，请手动同步', 'data' => json_encode($delResponse)]);
                }
            }
        }
        //更新mysql es_id;
        try {
            $updateRes = $model->isUpdate(true)->saveAll($updateData);
            if (!$updateRes) {
                throw new DbException('批量更新失败', '');
            }
        } catch (DbException $exception) {
            Db::rollback();
            $delResponse = $doc->deleteByBatch(ES::TOPIC_INDEX, ES::TOPIC_TYPE, $history_es);
            if ($delResponse['result'] !== 'deleted') {
                return json(['status' => 0, 'msg' => '同步失败，请手动同步', 'data' => json_encode($delResponse)]);
            }
            return ['status' => 0, 'msg' => $exception->getMessage()];
        }
        Db::commit();
        return json(['status' => 1, 'msg' => '更新成功,正在更新下一批数据 。当前页码：' . $request_data['page']]);
    }
}